package team.scau.laboratory_repair.service;

import lombok.extern.apachecommons.CommonsLog;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import team.scau.laboratory_repair.common.quartz.jobs.repair.SuperviseJob;

import java.util.Date;
import java.util.Map;

import static team.scau.laboratory_repair.common.utils.DateTool.TimeUnit.*;
import static team.scau.laboratory_repair.common.utils.DateTool.*;

/**
 * @author 30254
 * creadtedate:2018/9/17
 */
@Service
@CommonsLog
public class JobService {

    @Autowired
    private Scheduler scheduler;

    public void addJob(String id, Class<? extends Job> jobClazz, String schedule, Map<String, Object> data) throws Exception {
        JobDetail job = JobBuilder.newJob(jobClazz)
                .withIdentity(JobKey.jobKey(id))
                .build();
        job.getJobDataMap().putAll(data);
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(TriggerKey.triggerKey(id))
                .withSchedule(CronScheduleBuilder.cronSchedule(schedule).withMisfireHandlingInstructionDoNothing())
                .build();

        scheduler.scheduleJob(job, trigger);
    }

    public void addJobWithDayUnit(String id, Class<? extends Job> jobClazz, int interval, Map<String, Object> data) throws Exception {
        Date date = new Date();
        String schedule = String.valueOf(getUnitData(date, SECOND)) + ' ' + getUnitData(date, MINUTE) + ' ' +
                getUnitData(date, HOUR) + " */" + interval + " * ?";
        JobDetail job = JobBuilder.newJob(jobClazz)
                .withIdentity(JobKey.jobKey(id))
                .build();
        job.getJobDataMap().putAll(data);
        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity(TriggerKey.triggerKey(id))
                .withSchedule(CronScheduleBuilder.cronSchedule(schedule).withMisfireHandlingInstructionDoNothing())
                .build();

        scheduler.scheduleJob(job, trigger);
    }

    public boolean updateJob(String id, String schedule) throws Exception{
        boolean b = checkExists(id);
        if(b) {
            CronTrigger trigger = (CronTrigger) getTrigger(id);
            if (trigger != null) {
                trigger = trigger.getTriggerBuilder().withIdentity(TriggerKey.triggerKey(id))
                        .withSchedule(CronScheduleBuilder.cronSchedule(schedule).withMisfireHandlingInstructionDoNothing()).build();
                scheduler.rescheduleJob(TriggerKey.triggerKey(id), trigger);
            }
        }
        return b;
    }

    public void updateJobData(String id, Map<String, Object> newDatas) throws Exception {
        JobDataMap dataMap = scheduler.getJobDetail(JobKey.jobKey(id)).getJobDataMap();
        dataMap.putAll(newDatas);
        JobDetail newJob = JobBuilder.newJob(SuperviseJob.class).withIdentity(id).storeDurably().build();
        newJob.getJobDataMap().putAll(dataMap);
        scheduler.addJob(newJob, true);
//
//        scheduler.addJob(, true);
    }

    public boolean checkExists(String identity) throws Exception{
        return scheduler.checkExists(TriggerKey.triggerKey(identity));
    }

    public Trigger getTrigger(String identity) throws Exception{
        if(checkExists(identity)){
            return scheduler.getTrigger(TriggerKey.triggerKey(identity));
        }
        return null;
    }

    public void removeSchedule(String id) throws SchedulerException {
        if (scheduler.checkExists(TriggerKey.triggerKey(id))) {
            scheduler.pauseJob(JobKey.jobKey(id));
            scheduler.unscheduleJob(TriggerKey.triggerKey(id));
        }
        if (scheduler.checkExists(JobKey.jobKey(id))) {
            scheduler.deleteJob(JobKey.jobKey(id));
        }
    }
}
